﻿using System;

namespace Cpu6502.Opcodes
{
    /// <summary>
    /// LDY #AA - Immediate Mode
    /// Loads Value directly into the Y register.
    /// </summary>
    class LDY_I : Opcode
    {
        public LDY_I()
        {
            this.CpuCycles = 2;
            this.AddressType = CPU.AddressType.Immediate;
        }

        public override void Execute()
        {
            CPU.Registers.Y = (byte)base.Argument;

            // Set the Zero Flag if the data is 0
            CPU.Registers.P.Z = (base.Argument == 0);

            // If bit 7 of accumulator is set, then Negative flag must be set.
            CPU.Registers.P.N = (((base.Argument << 7) & 1) != 0);   
        }
    }

    /// <summary>
    /// LDY $AAAA - LDY Absolute Mode
    /// Loads Value from memory into Register Y
    /// </summary>
    public class LDY_A : Opcode
    {
        public LDY_A()
        {
            this.CpuCycles = 4;
            this.AddressType = CPU.AddressType.Absolute;
        }

        public override void Execute()
        {
            CPU.Registers.Y = CPU.Memory[base.Argument];
          
            // Set the Zero Flag if the data is 0
            CPU.Registers.P.Z = (CPU.Registers.Y == 0);

            // If bit 7 of accumulator is set, then Negative flag must be set.
            CPU.Registers.P.N = (((CPU.Registers.Y << 7) & 1) != 0);   
        }
    }

    /// <summary>
    /// LDY $AAAA, X - LDY Absolute X Mode
    /// Loads Value from memory into Register Y
    /// </summary>
    public class LDY_A_X : Opcode
    {
        public LDY_A_X()
        {
            this.CpuCycles = 4;
            this.AddressType = CPU.AddressType.AbsoluteIndexedX;
        }

        public override void Execute()
        {
            CPU.Registers.Y =
                CPU.Memory
                [
                    MemoryHelper.GetAddress
                    (base.Argument,
                    CPU.AddressType.AbsoluteIndexedX)
                ];

            // Set the Zero Flag if the data is 0
            CPU.Registers.P.Z = (CPU.Registers.Y == 0);

            // If bit 7 of accumulator is set, then Negative flag must be set.
            CPU.Registers.P.N = (((CPU.Registers.Y << 7) & 1) != 0);   
        }
    }

    /// <summary>
    /// LDY $AA - LDY ZeroPage Mode
    /// Loads Value from memory into register Y
    /// </summary>
    public class LDY_ZP : Opcode
    {
        public LDY_ZP()
        {
            this.CpuCycles = 3;
            this.AddressType = CPU.AddressType.ZeroPage;
        }

        public override void Execute()
        {
            CPU.Registers.Y =
                CPU.Memory
                [
                    MemoryHelper.GetAddress
                    (base.Argument,
                    CPU.AddressType.ZeroPage)
                ];

            // Set the Zero Flag if the data is 0
            CPU.Registers.P.Z = (CPU.Registers.Y == 0);

            // If bit 7 of accumulator is set, then Negative flag must be set.
            CPU.Registers.P.N = (((CPU.Registers.Y << 7) & 1) != 0);   
        }
    }

    /// <summary>
    /// LDY $AA, Y - LDY ZeroPage X Mode
    /// Loads Value from memory into Register Y
    /// </summary>
    public class LDY_ZP_X : Opcode
    {
        public LDY_ZP_X()
        {
            this.CpuCycles = 4;
            this.AddressType = CPU.AddressType.ZeroPageIndexedY;
        }

        public override void Execute()
        {
            CPU.Registers.Y =
                CPU.Memory
                [
                    MemoryHelper.GetAddress
                    (base.Argument,
                    CPU.AddressType.ZeroPageIndexedX)
                ];

            // Set the Zero Flag if the data is 0
            CPU.Registers.P.Z = (CPU.Registers.Y == 0);

            // If bit 7 of accumulator is set, then Negative flag must be set.
            CPU.Registers.P.N = (((CPU.Registers.Y << 7) & 1) != 0);   
        }
    }  
}
